import { getAccount } from '@/utils/dahua.player'
import http from '@/utils/http'
import formatDate from '@/utils/date'
import { registerEvent } from '@/utils/event.bus'

/**
 * @see https://open-gov.dahuatech.com/#/download
 */
class DahuaPlayerPlugin {
	/**
	 * 大华播放器插件版操作类
	 * @param {Object}    options             公共配置信息
	 * @param {String}    options.el          播放器容器 id, 创建多个播放器时, 传入不同的容器 id 即可
	 * @param {Boolean}   options.exclusion   是否与报警弹框互斥
	 */
	constructor(options = {}) {
		if (window.DHWs) {
			this.player = DHWs.getInstance()
		}
		this.el = options.el ?? 'dahua-player-plugin'
		// 是否与登录弹框互斥
		this.exclusion = options.exclusion ?? true
		this.refCode = options.refCode ?? `refDahuaPlugin${(Date.now() + '').substring(10)}`
		this.options = options
		this.ip = ''
		this.port = ''
		this.userCode = ''
		this.token = window.localStorage.getItem('psi_token') || window.sessionStorage.getItem('psi_token') || null
		this.origin = window.localStorage.getItem('wsplayer_origin') || window.sessionStorage.getItem('wsplayer_origin') || {}
		// console.log('🚀 ~ constructor ~ this.refCode:', this.refCode)
		this.inited = false

		// this.player?.on('closeWndMSG', (e) => {
		// 	console.log('🚀 ~ this.player.on(closeWndMSG) ~ e:', e)
		// })

		// this.player?.on('playerWinInfoNotify', (e) => {
		// 	console.log('🚀 ~ this.player.on(playerWinInfoNotify) ~ e:', e)
		// })

		this.listenerVideoOpen = registerEvent('dahua:open', () => {
			// console.log('🚀 ~ this.listenerVideoOpen=registerEvent ~ listenerVideoOpen(dahua:open)', this.exclusion)
			this.exclusion && this.hidden()
		})
		this.listenerVideoClose = registerEvent('dahua:close', () => {
			// console.log('🚀 ~ this.listenerVideoClose=registerEvent ~ listenerVideoClose(dahua:close)', this.exclusion)
			this.exclusion && this.visible()
		})
	}

	// 登录大华云平台
	login(callback) {
		if (!this.player) {
			console.warn('大华视频插件尚未实例化')
			return
		}

		console.log('do data plugin login')
		this.player.detectConnectQt().then((res) => {
			console.log('🚀 ~ this.player.detectConnectQt ~ res:', res)
			if (res) {
				// 连接视频插件成功
				// console.time('dahua login success')
		
				this.player.on('loginState', (r) => {
					console.log('🚀 ~ this.player.on ~ r:', r)
					if(r) {
						// console.timeEnd('dahua login success')
						console.log('do login success')
						this.token = window.localStorage.getItem('psi_token') || window.sessionStorage.getItem('psi_token') || null
						this.origin = window.localStorage.getItem('wsplayer_origin') || window.sessionStorage.getItem('wsplayer_origin') || {}
						callback?.()
					// 启动插件成功 
					} else {
					// 启动插件失败 
					}
				})

				if (this.player.isLoginSuccess && typeof callback === 'function') {
					callback?.()

					return
				}

				// const {
				// 	token,
				// 	encryptToken,
				// 	port,
				// 	ip
				// } = getAccount()
				// 	console.log('🚀 ~ this.player.detectConnectQt ~ token, encryptToken, port, ip:', token, encryptToken, port, ip)
		
				// if (token && encryptToken) {
				// 	this.player.login({
				// 		verifyCode: encryptToken,
				// 		token,
				// 		loginIp: ip,// 视频云平台 IP 
				// 		loginPort: port, // 视频云平台端口 
				// 		https: 0 // 1 为使用 https 加密模式， 0 为使用 http 非加密模式 
				// 	})
				// } else {
					// console.time('get camera server')
					http.get('/common/cameraServer', {}).then(res => {
						if (res.code == 1) {
							this.ip = res.data.vms_ip
							this.port = res.data.vms_port

							// console.timeEnd('get camera server')
							this.player.login({
								// 视频云平台 IP 
								loginIp: res.data.vms_ip,
								loginPort: res.data.vms_port,//视频云平台端口 
								userName: res.data.vms_user,//用户名 
								userPwd: res.data.vms_psw,//密码
								https: 0
							})
						}
					})
				// }
			}
		})
	}

	/**
	 * 根据预置点，执行云台控制
	 * @param {String} channel 视频通道
	 * @param {Number} index   预置点
	 * @returns 
	 */
	ptzMoveByIndex(channel, index) {
		console.log('🚀 ~ ptzMoveByIndex ~ channel, index:', channel, index)
		const token = this.token
		const origin = this.origin
		console.log('🚀 ~ ptzMoveByIndex ~ token, origin:', token, origin)

		if (!token) {
			return
		}

		fetch(`/videoService/ptz/preset/goto/channels/${channel}/${index}`, {
			method: 'PUT',
			headers: {
				'X-Subject-Token': token,
				'Content-Type': 'application/json',
				'Self-TargetOrigin': origin
			},
			body: JSON.stringify({
				speed: 0.5
			})
		})
	}

	// 初始化带云台的插件贴片
	initPtzLayout () {
		if (!this.player) {
			console.warn('大华视频插件尚未实例化')
			return
		}

		if (this.inited) {
			this.destroy(true)
		}

		this.player.createCtrl([
			{
				domId: this.el,
				visible: true,
				ctrlType: 'realMonitorUI',
				ctrlCode: this.refCode,
				ctrlProperty: {
					toWall: true,
					splitNum: 4
				}
			}
		])

		this.inited = true
	}

	/**
	 * 初始化插件贴片
	 * @param type [1: 实时视频 2: 录像播放]
	 */
	initLayout (type = 1, channels = []) {
		console.log('🚀 ~ initLayout ~ channels:', channels)
		if (this.inited) {
			this.destroy(true)
		}

		const option = [
			{
				domId: this.el,
				visible: true,
				ctrlType: 'playerWin',
				ctrlCode: this.refCode,
				ctrlProperty: {
					displayMode: type
				}
			}
		]

		if (channels.length) {
			option[0].ctrlProperty.channelList = channels.map((node, index) => {
				const chl = {
					channelId: node.channelCode,
					index
				}

				if (node.usePtz) {
					this.ptzMoveByIndex(node.channelCode, node.ptz)
				}

				if (node.beginTime) {
					chl.beginTime = formatDate(node.beginTime, 'YYYY-MM-DD hh:mm:ss')
				}

				if (node.endTime) {
					chl.endTime = formatDate(node.endTime, 'YYYY-MM-DD hh:mm:ss')
				}

				return chl
			})

			option[0].ctrlProperty.splitNum = this.fotmatChannelCount(channels.length)
		} else {
			option[0].ctrlProperty.splitNum = 4
		}

		this.player.createCtrl(option)

		if (type == 2 && channels.length) {
			this.player.transparent('setVideoSyncPlay', {
				ctrlCode: this.refCode,
			})
		}

		this.inited = true
	}

	visible () {
		if (!this.player) {
			console.warn('大华视频插件尚未实例化')
			return
		}

		if (!this.inited) {
			return
		}

		console.log('🚀 ~ visible ~ dahua plugin visible')
		this.player.setCtrlVisible([{
			ctrlCode: this.refCode,
			visible: true
		}])
	}

	hidden () {
		if (!this.player) {
			console.warn('大华视频插件尚未实例化')
			return
		}

		console.log('🚀 ~ visible ~ dahua plugin hidden')
		this.player.setCtrlVisible([{
			ctrlCode: this.refCode,
			visible: false
		}])
	}

	/**
	 * 销毁播放器
	 * @param reset 是否只是重置 layout
	 */
	destroy(reset) {
		if (!this.player) {
			console.warn('大华视频插件尚未实例化')
			return
		}

		this.player.destroyCtrl([this.refCode])
		this.inited = false

		if (!reset) {
			// this.player.logout({})
			this.listenerVideoOpen.destroy()
			this.listenerVideoClose.destroy()
			this.listenerVideoOpen = null
			this.listenerVideoClose = null
		}
	}

	/**
	 * 播放实时视频
	 * eq. {
	 * channelList : [
	 *    {
	 *      channelCode : 'xxxx',
	 *    } 
	 *  ],
	 * @param {Object[]} channelList 
	 * @param {String}   channelList.channelCode  通道编码 code
	 */
	playRealVideo(channelList) {
		if (channelList.length < 1) {
			console.log('channelList 为空')

			return
		}

		if (!this.inited) {
			this.initLayout(1)
		}

		this.player.openCtrlPreview({
			ctrlCode: this.refCode,
			channelIds: channelList.map(chl => chl.channelCode)
		})
	}

	/**
	 * 播放录像
	 * eq. {
	 * channelList : [
	 *    {
	 *      channelCode : 'xxxx',
	 *    } 
	 *  ],
	 *  startTime: '2024-01-01 00:00:00',
	 *  endTime: '2024-01-01 23:59:59'
	 * @param {Object[]}   channelList 
	 * @param {String}     channelList.channelCode      通道编码 code
	 * @param {Timestamp}  startTime   录像开始时间，YYYY-MM-DD hh:mm:ss 格式的时间
	 * @param {Timestamp}  endTime     录像结束时间，YYYY-MM-DD hh:mm:ss 格式的时间
	 */
	playRecordVideo({ channelList, startTime, endTime }) {
		console.log('🚀 ~ playRecordVideo ~ channelList, startTime, endTime:', channelList, startTime, endTime)
		if (channelList.length < 1) {
			console.log('channelList 为空')

			return
		}

		if (!this.inited) {
			this.initLayout(2)
		}

		this.player.openCtrlRecord([
			{
				ctrlCode: this.refCode,
				array: channelList.map(chl => {
					return {
						channelId: chl.channelCode,
						beginTime: startTime,
						endTime: endTime,
						index: chl.index ?? -1
					}
				})
			}
		])

		this.player.transparent('setVideoSyncPlay', {
			ctrlCode: this.refCode,
		})
	}

	/**
	 * 下载录像
	 * @param {Object[]}   channelList 
	 * @param {String}     channelList.channelName  通道名称
	 * @param {String}     channelList.channelCode  通道编码 code
	 * @param {Timestamp}  startTime  录像开始时间，单位: 秒
	 * @param {Timestamp}  endTime    录像结束时间，单位: 秒，如果 startTime 和 endTIme 不是同一天时，以有录像的第一天进行播放
	 */
	downloadVideo ({ channelList, startTime, endTime }) {
		console.log('🚀 ~ downloadVideo ~ channelList:', channelList, startTime, endTime)
		if (channelList.length < 1) {
			console.log('channelList 为空')

			return
		}

		/**
			 * -  arr.channelName:下载文件名称前缀。
			 * -  arr.channelId:下载文件通道编码。
			 * -  arr.beginTime:时间戳，前端使用Date对象时，注意去掉后三位。
			 * -  arr.endTime:时间戳，前端使用Date对象时，注意去掉后三位。
			 * -  arr.format:下载文件格式，0-dav;1-avi;2-mp4。
			 * -  arr.sourceType:下载文件录像类型，2-设备录像；3-中心录像。
			 * -  arr.streamType:下载文件码流，1-主码流；2-辅码流；3-三码流。
			 * -  isShowDiolog：是否显示下载的弹窗，此处表示的不是属性名，而是值，其值为true或false，可不传。如果传了此参数则会对下载窗口进行显示和隐藏的控制，否则默认之前的状态。
			*/
		this.player.downloadVideo(
			channelList.map(chl => {
				return {
					channelName: chl.channelName,
					channelId: chl.channelCode,
					beginTime: startTime,
					endTime: endTime,
					format: 2,
					sourceType: 3,
					streamType: 1
				}
			}),
			true
		)
	}

	// 根据通道数量，获取需要初始化的数量
	fotmatChannelCount(channelNumber) {
		// 直接返回 [1, 4, 9, 16, 25] 的方案
		return channelNumber > 0 && channelNumber <= 9
		  ? Math.pow(Math.ceil(Math.sqrt(channelNumber)), 2)
		  : 1
	}

	// 根据通道数量，获取可显示的最大数量
	fotmatChannelMax(channelNumber) {
		return channelNumber > 0 && channelNumber <= 25
			? Math.pow(Math.ceil(Math.sqrt(channelNumber)), 2)
			: 25
	}
}

export default DahuaPlayerPlugin